/*
 * Jiri Cigler
 * ciglej1@fel.cvut.cz 
 *
 * Copyright (C) 2007 Jirka Cigler <ciglej1@fel.cvut.cz>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */ 



/*
 * =============================================================
 * jobshop.cpp - program for computing job shop problem
 *
 * Computational function that takes 2 arguments
 *  jobshop(resources, duration, machines)
 *  
 *  resources ... matrix N x M 
 *  duration  ... matrix N x M
 *	where N is number of jobs ( rows of the matrix )
 *	      M is number of tasks in each job ( columns of the matrix )
 * This is a MEX-file for MATLAB.
 * =============================================================
 */

/* $Revision: 1.0 $ */

#include "mex.h"
#include "scheduler.hh"
double runtime;
unsigned int** jobshop( int **& resources, unsigned int **& duration, int jobs, int tasks , int machines)
{
	unsigned int **r;
	r = new unsigned int*[tasks];//tasksinjob
	for( int x = 0; x < tasks; x++ )
		r[x] = new unsigned int[jobs];//jobs
	
	run(resources,duration,jobs,tasks,machines, r,&runtime);
	for(int i=0; i < jobs ; i++){
		for(int j = 0; j<tasks; j++){
			printf("%d ",r[i][j]);
		}
		printf("\n");
	}
	return r;
}

template <class T>
T** convertFromMxArray(const mxArray *a, char verbose){
	int rows = mxGetM(a);
	int columns = mxGetN(a);
	T** res;
	res = new T*[columns];
	for( int x = 0; x < columns; x++ )
		res[x] = new T[rows];
	int i, j;
	double * data = mxGetPr(a);
	for(i =0; i < columns; i++){
		for(j =0; j < rows ; j++){
			res[j][i] = (T)*data;
			if(verbose)
				printf(" %f",*data);
			data++;
		}
		if(verbose)
			printf("\n");
	}
	return res;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
		const mxArray *prhs[])
{
	int mrows, ncols, jobs, tasksInJob, machines;

	if(nrhs !=2){
		mexErrMsgTxt("Two inputs required.");
	}
	else if(nlhs!=2){
		mexErrMsgTxt("Too many output arguments");
	}
	else{
		/* The input must be a noncomplex scalar double.*/
		mrows = mxGetM(prhs[1]);
		ncols = mxGetN(prhs[1]);  
		/*if (!mxIsDouble(prhs[2]) || mxIsComplex(prhs[2]) || !(mrows == 1 && ncols == 1)) {
		  mexErrMsgTxt("machines must be a noncomplex scalar double.");
		  }*/
		machines = mrows; 
		printf("machines %d\n",machines);
		if(mxGetM(prhs[1])!=mxGetM(prhs[0]) || mxGetN(prhs[1])!=mxGetN(prhs[0]) )
			mexErrMsgTxt("Matrixes must have same dimension");
		tasksInJob = mxGetN(prhs[0]);
		jobs = mxGetM(prhs[0]);
		plhs[0] = mxCreateDoubleMatrix(jobs,tasksInJob, mxREAL);
		plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
		unsigned int ** duration = convertFromMxArray<unsigned int>(prhs[1],1);
		printf("duration converted .. OK\n");
		int ** resources = convertFromMxArray<int>(prhs[0],1);
		printf("resources converted .. OK\n");
		unsigned int** result = jobshop(resources, duration,  jobs,  tasksInJob ,  machines);
		printf("result converted .. OK\n");


		double *data = mxGetPr(plhs[0]);
		for(int i=0; i < tasksInJob ; i++){
			for(int j=0; j < jobs; j++){
				*data = result[j][i];
				data++;
			}
		}
		printf("result converted .. OK\n");
		data = mxGetPr(plhs[1]);
		*data = runtime;

		printf("result converted .. OK\n");
		for (int i=0; i<jobs; i++){
			delete result[i];
			delete duration[i];
			delete resources[i];
		}
		delete result;
		delete duration;
		delete resources;
		double * d = mxGetPr(plhs[1]);
		//*d =(double)timeFinish -timeStart;
	}
};

